package com.foruo.demo.jdbc.datasource;

import com.foruo.demo.jdbc.ConnectionUtils;
import com.foruo.demo.jdbc.config.JDBCConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.TimeUnit;

/**
 * 连接池中心
 * @author GaoYuan
 */
@Component
public class MyDataSource {

    @Autowired
    ConnectionUtils connectionUtils;
    @Autowired
    JDBCConfig jdbcConfig;

    /** 空闲线程池 （当程序使用一个连接时，freePool-1，activePool+1） */
    private static List<Connection> freePool =  new Vector<>();
    /** 活动线程池 */
    private static List<Connection> activePool = new Vector<>();

    /** 初始化n个连接 */
    public void initConnection(){
        int initialSize = Integer.parseInt(jdbcConfig.getInitialSize());
        // 初始化创建n个连接 - 存入空闲连接池
        for(int i=0;i<initialSize;i++){
            freePool.add(connectionUtils.getConnection());
        }
    }

    /**
     * 从连接池中获取连接
     * @author GaoYuan
     */
    public Connection getConnection(){
        if(freePool.isEmpty()){
            /** 当空闲池中没有连接时，需要做什么
             * 1、返回错误
             * 2、继续获取新的连接
             * 3、等待
             * */
            if(activePool.isEmpty()){
                initConnection();
            }
            // 等待并重新get
            try {
                System.out.println("!!!!!!! 没有空闲连接，那就等待一会儿！！！！！");
                // 为了测试，2秒后重新获取
                TimeUnit.SECONDS.sleep(2);
                return getConnection();
            }catch (Exception e){

            }
        }
        Connection connection = freePool.get(0);
        System.out.println("###### 获取连接 ##### " + connection.hashCode());
        freePool.remove(0);
        activePool.add(connection);
        return connection;
    }

    public void close(Connection connection, Statement statement, ResultSet resultSet){
        try{
            if(resultSet != null){
                resultSet.close();
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (statement != null) {
                    statement.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                if(connection != null){
                    activePool.remove(0);
                    freePool.add(connection);
                }
            }
        }
    }

}
